import java.util.HashMap;
import java.util.Map;
import java.util.stream.IntStream;

class FoodChain {

    private final static Map<Integer, Lyrics> NUMBER_ANIMAL = new HashMap<>() {
        {
            put(1, new Lyrics("fly", ""));
            put(2, new Lyrics("spider", "It wriggled and jiggled and tickled inside her.\n"));
            put(3, new Lyrics("bird", "How absurd to swallow a bird!\n"));
            put(4, new Lyrics("cat", "Imagine that, to swallow a cat!\n"));
            put(5, new Lyrics("dog", "What a hog, to swallow a dog!\n"));
            put(6, new Lyrics("goat", "Just opened her throat and swallowed a goat!\n"));
            put(7, new Lyrics("cow", "I don't know how she swallowed a cow!\n"));
            put(8, new Lyrics("horse", ""));
        }
    };

    String verse(final int inputNumber) {
        StringBuilder result = new StringBuilder();

        result
                .append(String.format("I know an old lady who swallowed a %s.\n", FoodChain.NUMBER_ANIMAL.get(inputNumber).getAnimal()))
                .append(FoodChain.NUMBER_ANIMAL.get(inputNumber).getLyrics());

        this.verse(inputNumber, result);

        if (inputNumber == 8) {
            result.append("She's dead, of course!\n");
        } else {
            result.append("I don't know why she swallowed the fly. Perhaps she'll die.\n");
        }

        return result.substring(0, result.length() - 1);
    }

    private void verse(int inputNumber, StringBuilder result) {
        if (inputNumber == 1 || inputNumber == 8) {
            return;
        }

        String animal1 = FoodChain.NUMBER_ANIMAL.get(inputNumber).getAnimal();
        String animal2 = FoodChain.NUMBER_ANIMAL.get(inputNumber - 1).getAnimal();
        result.append(String.format("She swallowed the %s to catch the %s%s.\n",
                animal1,
                animal2,
                animal1.equals("bird") ? " that wriggled and jiggled and tickled inside her" : ""));

        this.verse(inputNumber - 1, result);
    }

    String verses(final int startVerse, final int endVerse) {
        StringBuilder result = new StringBuilder();

        IntStream.range(startVerse, endVerse + 1).forEach((i) -> result.append(this.verse(i)).append("\n\n"));
        return result.substring(0, result.length() - 2);
    }

    private static class Lyrics {

        private final String animal;
        private final String lyrics;

        Lyrics(String animal, String lyrics) {
            this.animal = animal;
            this.lyrics = lyrics;
        }

        public String getAnimal() {
            return animal;
        }

        public String getLyrics() {
            return lyrics;
        }
    }
}